package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/mosongcc/gotool/gcache"
	"gorm.io/gorm"
	"log/slog"
	"time"
	"vitepress-serve/internal/model"
)

type ConfigKey string

// 配置Key定义
const (
	WEB_SITE     ConfigKey = "website"      // 网站参数配置
	WEIXIN_OAUTH ConfigKey = "weixin_oauth" // 微信网页授权配置
	WEIXIN_PAY   ConfigKey = "weixin_pay"   //微信支付商户配置
)

var ErrConfigNotFound = errors.New("config not found")

type ConfigService struct {
	*Service
}

func NewConfigService(db *gorm.DB) *ConfigService {
	return &ConfigService{
		Service: &Service{db: db},
	}
}

func GetConfigValue[T any](service *ConfigService, key ConfigKey) (T, error) {
	return gcache.Load[T](gcache.Memory, "sys_config."+string(key), func() (v any, err error) {
		var conf model.SysConfig
		if err = service.db.Model(&conf).Where("key = ?", key).Take(&conf).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				slog.Info(fmt.Sprintf("%s.[%s] not found", conf.TableName(), key))
				err = ErrConfigNotFound
			}
			return
		}
		var t T
		err = json.Unmarshal([]byte(conf.Value), &t)
		if err != nil {
			return
		}
		v = t
		return
	}, 3*time.Minute)
}

func getConfigValue[T any](service *ConfigService, key ConfigKey) T {
	v, err := GetConfigValue[T](service, key)
	if err != nil {
		panic(err)
	}
	return v
}

// WebSite 网站参数
type WebSite struct {
}

func (service *ConfigService) WebSite() WebSite {
	return getConfigValue[WebSite](service, WEB_SITE)
}

// Wechat 微信公众号参数
type Wechat struct {
	Appid     string `json:"appid" toml:"appid" yaml:"appid"`
	Secret    string `json:"secret" toml:"secret" yaml:"secret"`
	CbBaseUrl string `json:"cb_base_url" toml:"cb_base_url" yaml:"cb_base_url"` // 回调示例 https://wechat-oauth2.mosong.cc/vitepress.mosong.cc/meb/weixin-oauth-callback?code=041cEU000N1iLS1pOP2003LhO72cEU0K&state=xxx
}

func (service *ConfigService) Wechat() (v Wechat) {
	return getConfigValue[Wechat](service, WEIXIN_OAUTH)
}

// Wxpay 微信支付参数
type Wxpay struct {
	ServiceUrl    string `json:"service_url" toml:"service_url" yaml:"service_url"`
	Mchid         string `json:"mchid" toml:"mchid" yaml:"mchid"`
	MchV3Secret   string `json:"mch_v3_secret" toml:"mch_v3_secret" yaml:"mch_v3_secret"`
	MchSerial     string `json:"mch_serial" toml:"mch_serial" yaml:"mch_serial"`
	MchPrivateKey string `json:"mch_private_key" toml:"mch_private_key" yaml:"mch_private_key"`
	SafeUrl       string `json:"safe_url" toml:"safe_url" yaml:"safe_url"` // 配置到微信支付后台的域名目录，调用JSAPI的域名，结尾不要/
	MchName       string `json:"mch_name"`                                 // 商户名称
}

func (service *ConfigService) Wxpay() (v Wxpay) {
	return getConfigValue[Wxpay](service, WEIXIN_PAY)
}
